package pers.vic.basics.datastructure.stack;

import java.util.Arrays;

/**
 * @author Vic.xu
 * @description:栈实现 ；可扩容
 * @date: 2020/10/15 0015 16:31
 */
public class VicStack<T> implements StackInterface<T> {

    /**
     * 存放数据的数组
     */
    private T[] arr;

    /**
     * 当前栈顶的位置
     */
    private int top;

    /**
     * 容量
     */
    private int capacity;

    private static final int DEFAULT_CAPACITY = 8;

    public VicStack() {
        this(DEFAULT_CAPACITY);
    }

    public VicStack(int capacity) {
        if (capacity < 1) {
            throw new IllegalArgumentException("容量需要大于0");
        }
        this.capacity = capacity;
        this.top = -1;
        this.arr = (T[]) new Object[capacity];

    }

    /**
     * 出栈 弹出数据
     */
    @Override
    public T pop() {
        T data = peek();
        arr[top] = null;
        top--;
        return data;
    }

    /**
     * 进栈  判断扩容
     */
    @Override
    public boolean push(T element) {
        resize();
        arr[++top] = element;
        return true;
    }

    /**
     * 2倍扩容
     */
    private boolean resize() {
        if (capacity == Integer.MAX_VALUE) {
            throw new IllegalStateException("栈无法再扩容了");
        }
        if (top + 1 < capacity - 1) {
            return false;
        }
        if ((capacity << 1) > Integer.MAX_VALUE) {
            this.capacity = Integer.MAX_VALUE;
        } else {
            this.capacity = capacity << 1;
        }
        this.arr = Arrays.copyOf(arr, capacity);
        return true;
    }

    /**
     * 访问栈数据
     */
    @Override
    public T peek() {
        if (isEmpty()) {
            throw new IllegalStateException("栈已经空了");
        }
        return arr[top];
    }


    @Override
    public boolean isEmpty() {
        return top == -1;
    }

    @Override
    public boolean isFull() {
        return top == (capacity - 1);
    }

    //打印栈的信息
    public void display() {
        System.out.println(String.format("栈容量[%d]，当前数量[%d]", capacity, (top + 1)));
        System.out.println(Arrays.toString(arr));

    }


}
